//
//  JRHttpRequestHelper.m
//  
//
//  Created by dingjiarui on 2021/7/26.
//

#import "JRHttpRequestHelper.h"
#import "JRAFNetworking.h"
#import "JRHttpRequestConstants.h"

NSTimeInterval const JRHttpRequestTimeoutInterval = 60;

@implementation JRHttpRequestHelper

+ (JRHttpRequestConstants *)httpRequestConstants {
    return [JRHttpRequestConstants constants];
}

#pragma mark 网络请求是否存在
+ (BOOL)requestExist:(NSString *)key opId:(NSString *)opId {
    return [JRHttpRequestHelper.httpRequestConstants operationForKey:key opId:opId] != nil;
}

#pragma mark 取消全局队列网络请求中key的网络请求
+ (void)basicHttpFileRequestCancel:(NSString *)key {
    
    [self basicHttpFileRequestCancel:key withOpId:nil];
    
}

#pragma mark 取消某队列中key的网络请求
+ (void)basicHttpFileRequestCancel:(NSString *)key withOpId:(nullable NSString *)opId {
    
    [JRHttpRequestHelper.httpRequestConstants cancelOperationWithKey:key withOpId:opId completion:^(NSOperation *operation) {
        if ([operation isKindOfClass:[NSOperation class]]) {
//            operation.userInfo = @{@"error":@"cancelError"};
//            ((NSOperation *)operation).userInfo = @{@"error":@"cancelError"};
        }
    }];
    
}

#pragma mark 取消某队列网络请求
+ (void)basicHttpFileRequestCancelAllWithOpId:(NSString *)opId {
    
    [JRHttpRequestHelper.httpRequestConstants cancelAllOperationsWithOpId:opId completion:^(NSOperation * _Nonnull operation) {
        
    }];

}

#pragma mark 取消所有网络请求
+ (void)basicHttpFileRequestCancelAll {
    
    [JRHttpRequestHelper.httpRequestConstants cancelAllOperations:^(NSOperation * _Nonnull operation) {
        
    }];

}

#pragma mark - Public Methods

#pragma mark 普通http请求
+ (id<JRHttpCallBackConvertible>)basicHttpRequestWithUrlString:(NSString *)urlString params:(NSDictionary *)params request:(JRHttpRequest)request {
    
    JRHttpCallBack *callBack = [[JRHttpCallBack alloc] init];
    
    if ([self requestExist:request.key opId:request.opId]) {
        return callBack;
    }
    
    NSURL *url = [NSURL URLWithString:urlString];
    
    if (url == nil) {
        if (callBack.failure) {
            NSError *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:-909 userInfo:@{NSLocalizedDescriptionKey:@"URL string does not conform to specification"}];
            callBack.failure(error);
        }
        return callBack;
    }
    
    NSMutableURLRequest *urlRequest = nil;
    if (request.method == JRAFHTTPRequestMethodJsonGet || request.method == JRAFHTTPRequestMethodJsonPost) {
        JRAFHTTPRequestMethod method = [[request.method componentsSeparatedByString:@"_"] lastObject];
        urlRequest = [[JRAFJSONRequestSerializer serializer]
                   requestWithMethod:method
                   URLString:urlString
                   parameters:params
                   error:nil];
    } else {
        urlRequest = [[JRAFHTTPRequestSerializer serializer]
                      requestWithMethod:request.method
                      URLString:urlString
                      parameters:params
                      error:nil];
    }

    urlRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    urlRequest.timeoutInterval = (request.timeout <= 0 ? JRHttpRequestTimeoutInterval : request.timeout);
    [urlRequest setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"];
    for (NSString *key in request.headerFields) {
        [urlRequest setValue:request.headerFields[key] forHTTPHeaderField:key];
    }

    JRAFURLSessionManager *urlSessionManager = [[JRAFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    urlSessionManager.securityPolicy.allowInvalidCertificates = YES;
    urlSessionManager.securityPolicy.validatesDomainName = NO;

    __block long long readBytes = 0, writtenBytes = 0;
    NSURLSessionDataTask *task = [urlSessionManager dataTaskWithRequest:[urlRequest copy] uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
        writtenBytes = uploadProgress.totalUnitCount;
    } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
        readBytes = downloadProgress.totalUnitCount;
    } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        
        [JRHttpRequestHelper.httpRequestConstants cancelOperationWithKey:request.key withOpId:request.opId completion:nil];
        
        if (error && callBack.failure) {
            callBack.failure(error);
        } else if (callBack.success) {
            callBack.success(response, responseObject);
        }
        
        if (callBack.traffic) {
            callBack.traffic(writtenBytes, readBytes);
        }

    }];
    
    [task resume];
    
//    [JRHttpRequestHelper.httpRequestConstants addOperationRequest:urlSessionManager.operationQueue key:request.key opId:request.opId];
    
    return callBack;
    
}

#pragma mark 普通http上传请求
+ (id<JRHttpCallBackConvertible>)basicHttpFileUploadWithUrlString:(NSString *)urlString params:(NSDictionary *)params names:(NSArray *)names resourcePaths:(NSArray *)resourcePaths request:(JRHttpRequest)request {
    
    JRHttpCallBack *callBack = [[JRHttpCallBack alloc] init];
    
    
    
    
    
    
    
    
    return callBack;
    
}

#pragma mark 普通http下载请求
+ (id<JRHttpCallBackConvertible>)basicHttpFileDownloadWithUrlString:(NSString *)urlString params:(NSDictionary *)params offset:(u_int64_t)offset savePath:(NSString *)savePath request:(JRHttpRequest)request {
    
    JRHttpCallBack *callBack = [[JRHttpCallBack alloc] init];
    
    
    
    
    
    
    
    
    return callBack;
    
}

@end
